﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Red.Controls.TimeLine.Core;
using Red.Controls.TimeLine.ViewModels;
using Red.Controls.ViewModels;

namespace Red.Controls.TimeLine.TracksTree
{
    #region Track Items Data Temaplate Selector

    public sealed class TrackItemsDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate TracksGroupDataTemplate { get; set; }
        public DataTemplate TrackDataTemplate { get; set; }

        public DataTemplate PointEventDataTemplate { get; set; }
        public DataTemplate DurationDataTemplate { get; set; }
        public DataTemplate TrackItemTemplate { get; set; }

        public override DataTemplate SelectTemplate( object item, DependencyObject container )
        {
            if ( item is TracksGroup )
            {
                return TracksGroupDataTemplate;
            }

            if ( item is Track )
            {
                return TrackDataTemplate;
            }

            if ( item is PointTrackEvent )
            {
                return PointEventDataTemplate;
            }

            if ( item is DurationTrackEvent )
            {
                return DurationDataTemplate;
            }

            return TrackItemTemplate;         
        }
    }

    #endregion

    #region TracksTreeContainterStyleSelector

    public sealed class TracksTreeContainterStyleSelector : StyleSelector
    {
        public Style TracksGroup { get; set; }
        public Style Track { get; set; }
        public Style TrackItem { get; set; }

        public override Style SelectStyle( object item, DependencyObject container )
        {
            if ( item is Track )
            {
                return Track;
            }

            if ( item is TracksGroup )
            {
                return TracksGroup;
            }

            if ( item is TrackItemBase )
            {
                return TrackItem;
            }

            return null;
        }
    }

    #endregion
    
    #region TracksTree

    class TracksTree : TreeView
    {
        #region Data

        private bool _isScrolling = false;
        private Point _previousPosition2D;
        private TimeLineControler _controler;

        #endregion

        #region Ctr

        public TracksTree()
        {            
            MouseLeftButtonDown += TimeTracksBackground_MouseLeftButtonDown;
            MouseLeftButtonUp += TimeTracksBackground_MouseLeftButtonUp;
            MouseLeave += TimeTracksBackground_MouseLeave;
            MouseMove += TimeTracksBackground_MouseMove;
           
            PreviewMouseWheel += new MouseWheelEventHandler( TimeTracksBackground_MouseWheel );
        }
            
        #endregion

        #region Dependency properties

        public TimeLineControler TimeTrackControler
        {
            get { return (TimeLineControler)GetValue( TimeControlerProperty ); }
            set { SetValue( TimeControlerProperty, value ); }
        }

        public static readonly DependencyProperty TimeControlerProperty =
            DependencyProperty.Register( "TimeTrackControler", typeof( TimeLineControler ), typeof( TracksTree ), 
                new PropertyMetadata( null, OnTimeControlerChange ) );

        private static void OnTimeControlerChange( DependencyObject d, DependencyPropertyChangedEventArgs e )
        {
            TracksTree tree = (TracksTree)d;

            tree._controler = (TimeLineControler)e.NewValue;
        }

        #endregion

        #region Scrolling functions

        private void TimeTracksBackground_MouseLeftButtonUp( object sender, MouseButtonEventArgs e )
        {
            _isScrolling = false;
            Mouse.OverrideCursor = null;
        }

        private void TimeTracksBackground_MouseMove( object sender, MouseEventArgs e )
        {
            if ( !_isScrolling )
                return;

            Point currentPosition = e.GetPosition( (TracksTree)sender );

            if ( _controler != null )
            {
                double units = ActualWidth / _controler.MajorIntervalSizePx;
                double delta = ( currentPosition.X - _previousPosition2D.X ) / ActualWidth;

                double timeDelta = ( units * _controler.MajorIntervalUnit ) * delta;

                _controler.MoveStartTime( timeDelta );
            }

            _previousPosition2D = currentPosition;
        }

        private void TimeTracksBackground_MouseLeftButtonDown( object sender, MouseButtonEventArgs e )
        {
            _isScrolling = true;
            _previousPosition2D = e.GetPosition( (TracksTree)sender );

            Mouse.OverrideCursor = Cursors.ScrollWE;
        }

        private void TimeTracksBackground_MouseLeave( object sender, MouseEventArgs e )
        {
            _isScrolling = false;
            Mouse.OverrideCursor = null;
        }

        #endregion

        #region Zooming functions

        private void TimeTracksBackground_MouseWheel( object sender, MouseWheelEventArgs e )
        {
            if ( _controler != null )
            {
                _controler.Scale( e.Delta );
            }

            e.Handled = true;
        }

        #endregion
    }

    #endregion
}
